using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows.Forms;

namespace ICSharpCode.WinFormsUI.Controls
{
	public partial class NTreeNode
	{
		private NTreeNodeCollection _nodes;
		private ReadOnlyNTreeNodeCollection _children;

        #region Properties

        private string _identity;
        internal string Identity
        {
            get { return _identity; }
            set
            {
                if (_identity == "identity" || _identity == "")
                    _identity = value;
            }
        }

        //private bool _isLocked;
        //internal bool IsLocked
        //{
        //    get { return _isLocked; }
        //    set { _isLocked = value; }
        //}

		private NTreeView _tree;
		internal NTreeView Tree
		{
			get { return _tree; }
            set
            {
                _tree = value;
                this.Nodes.SetTree(_tree);
            }
		}

		private int _row;
		internal int Row
		{
			get { return _row; }
			set { _row = value; }
		}

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _text;
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }

        private object _tag;
        public object Tag
        {
            get { return _tag; }
            set { _tag = value; }
        }

        private string _toolTipText;
        public string ToolTipText
        {
            get { return _toolTipText; }
            set { _toolTipText = value; }
        }

        private int _imageIndex = -1;
        public int ImageIndex
        {
            get { return _imageIndex; }
            set { _imageIndex = value; }
        }

        private int _selectedImageIndex = -1;
        public int SelectedImageIndex
        {
            get { return _selectedImageIndex; }
            set { _selectedImageIndex = value; }
        }

        private bool _isSelected;
		public bool IsSelected
		{
			get { return _isSelected; }
			set 
			{
				if (_isSelected != value)
				{
					_isSelected = value;
					if (Tree.IsMyNode(this))
					{
						if (_isSelected)
						{
							if (!_tree.Selection.Contains(this))
								_tree.Selection.Add(this);

							if (_tree.Selection.Count == 1)
								_tree.CurrentNode = this;
						}
						else
							_tree.Selection.Remove(this);
						_tree.UpdateView();
						_tree.OnSelectionChanged();
					}
				}
			}
		}

		private bool _isLeaf;
		public bool IsLeaf
		{
			get {
                //if (_tree == null || _tree.Model == null)
                //    return _nodes.Count == 0;
                return _isLeaf;
            }
			internal set { _isLeaf = value; }
		}

		private bool _isExpandedOnce;
		public bool IsExpandedOnce
		{
			get { return _isExpandedOnce; }
			internal set { _isExpandedOnce = value; }
		}

		private bool _isExpanded;
		public bool IsExpanded
		{
			get { return _isExpanded; }
			set 
			{ 
				if (Tree.IsMyNode(this) && _isExpanded != value)
				{
                    if (value)
                        Tree.OnBeforeExpand(this);
                    else
                        Tree.OnBeforeCollapse(this);

                    if (value)
						Tree.OnExpanding(this);
					else
						Tree.OnCollapsing(this);

					if (value && !_isExpandedOnce)
					{
						Cursor oldCursor = Tree.Cursor;
						Tree.Cursor = Cursors.WaitCursor;
						try
						{
							Tree.ReadChilds(this);
						}
						finally
						{
							Tree.Cursor = oldCursor;
						}
					}
					_isExpanded = value; //&& CanExpand;
					if (_isExpanded == value)
						Tree.SmartFullUpdate();
					else
						Tree.UpdateView();

					if (value)
						Tree.OnExpanded(this);
					else
						Tree.OnCollapsed(this);
				}
			}
		}

        private bool _isChecked;
        public bool IsChecked
        {
            get { return _isChecked; }
            set
            {
                _isChecked = value;
            }
        }

		private NTreeNode _parent;
		public NTreeNode Parent
		{
			get { return _parent; }
			internal set { _parent = value; }
		}

		public int Level
		{
			get
			{
				if (_parent == null)
					return -1;
				else
					return _parent.Level + 1;
			}
		}

        private object _tagNode;
        internal object TagNode
        {
            get { return _tagNode; }
            set { _tagNode = value; }
        }

        internal NTreeNode NextNode
		{
			get
			{
				if (_parent != null)
				{
					int index = _parent.Nodes.IndexOf(this);
					if (index < _parent.Nodes.Count - 1)
						return _parent.Nodes[index + 1];
				}
				return null;
			}
		}

		internal NTreeNode BottomNode
		{
			get
			{
				NTreeNode parent = this.Parent;
				if (parent != null)
				{
					if (parent.NextNode != null)
						return parent.NextNode;
					else
						return parent.BottomNode;
				}
				return null;
			}
		}

        internal bool CanExpand
		{
			get
			{
				return (_nodes.Count > 0 || (!IsExpandedOnce && !IsLeaf));
			}
		}

		public NTreeNodeCollection Nodes
		{
			get { return _nodes; }
		}

		public ReadOnlyNTreeNodeCollection Children
		{
			get
			{
				return _children;
			}
		}

        #endregion

        #region Functions

        public void Expand()
        {
            if (_tree != null)
            {
                _isExpanded = true;
                _tree.OnExpanded(this);
                _tree.SmartFullUpdate();
                //this.IsExpanded = true;
            }
        }

        public void ExpandAll()
        {
            if (_tree != null)
            {
                for (int i = 0; i < _nodes.Count; i++)
                {
                    _nodes[i].ExpandAll();
                }
                _isExpanded = true;
                _tree.OnExpanded(this);
                _tree.SmartFullUpdate();
                //this.IsExpanded = true;
            }
        }

        #endregion

        internal NTreeNode(NTreeView tree, object tag)
		{
			_row = -1;           
            _tree = tree;
            _tagNode = tag;
            _imageIndex = -1;
            _selectedImageIndex = -1;
            _identity = "identity";
            _nodes = new NTreeNodeCollection(tree, this);
			_children = new ReadOnlyNTreeNodeCollection(_nodes);			
		}

        public NTreeNode()
        {
            _row = -1;           
            _imageIndex = -1;
            _selectedImageIndex = -1;
            _identity = "identity";
            _nodes = new NTreeNodeCollection(this);
            _children = new ReadOnlyNTreeNodeCollection(_nodes);
        }

        public override string ToString()
		{
			if (Text != null)
				return Text.ToString();
			else
				return base.ToString();
		}
	}
}
